package com.woniu.aimd.service.impl;

import com.woniu.aimd.mapper.NodeMapper;

import com.woniu.aimd.pojo.DTO.NodeBaseInfo;
import com.woniu.aimd.pojo.DTO.NodeQueryDTO;
import com.woniu.aimd.pojo.DTO.StageInfo;
import com.woniu.aimd.pojo.entity.Node;
import com.woniu.aimd.service.NodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author zcnovice
 * @data 2025/6/10 上午12:55
 */
@Service
public class NodeServiceImpl implements NodeService {

    @Autowired
    private NodeMapper nodeMapper;

    @Autowired
    private RedisTemplate<String,Node> redisTemplate;

    /**
     * 增加节点
     * 增加redis缓存方案
     * @param node
     * @return
     */

//    @CachePut(value = "nodeCache", key = "#node.nodeId")
    @Override
    public Node insert(Node node) {
        System.out.println("新增节点："+node);
        NodeBaseInfo newNodeInfo = new NodeBaseInfo(node.getNodeId(), node.getTitle(), node.getContent(), node.getClassId(), node.getStage());
        //把新增的节点信息存入redis中,使用hash存储
        redisTemplate.opsForHash().put("newNode",node.getNodeId(),node);
        //同步新增到nodeCache中
        redisTemplate.opsForHash().put("nodeCache",node.getNodeId(),newNodeInfo);
            return node;
//        }
//      return  null;
    }

    /**
     * 新增node定时存入数据库
     */
    public void processNewNodesFromRedis() {
        System.out.println("新增node的定时任务");
        //读取redis中所有新增的节点信息
        Map<Object,Object> keyNewNode = redisTemplate.opsForHash().entries("newNode");
        if (keyNewNode != null){
            Set<Object> keys = keyNewNode.keySet();
            for (Object key : keys) {
                Node newNode = (Node) keyNewNode.get(key);
                //把新增的节点信息存入数据库中
                System.out.println("把redis中的新增节点存入数据库："+newNode);
                nodeMapper.insert(newNode);
            }
            //存入数据库中的所有节点信息，从redis中清除
            redisTemplate.delete("newNode");
        }else {
            System.out.println("没有新增的节点");
        }
    }
    /**
     * 根据班级id获取该班级下的所有阶段以及每个阶段对应的节点信息
     * @param nodeQueryInfo
     * @return
     */
    @Override
    public List<StageInfo> getNodeInfo(NodeQueryDTO nodeQueryInfo) {
        //根据classId查询所有对应的阶段
        List<Integer> stages = nodeMapper.getStagesByClassId(nodeQueryInfo.getClassId());
        Map<Object,Object> nodesInRedis = null;
        //如果redis中key为newNode的数据存在
        if (redisTemplate.hasKey("newNode")){
            //从redis中获取节点信息
            nodesInRedis = redisTemplate.opsForHash().entries("newNode");
        }
        if (redisTemplate.hasKey("updateNode")){
            if (nodesInRedis == null){
                nodesInRedis = redisTemplate.opsForHash().entries("updateNode");
            }else {
                nodesInRedis.putAll(redisTemplate.opsForHash().entries("updateNode"));
            }
        }
        List<StageInfo> stageInfos = new ArrayList<>();
        for (Integer stage : stages) {
            System.out.print(stage);
            Node node = new Node(null, null, null, nodeQueryInfo.getClassId(), null, stage, null, null, null, null);
            //从数据库中获取节点信息
            List<NodeBaseInfo> nodeBaseInfos = nodeMapper.getNodeInfo(node);
            //判断redis中是否有新增和修改的内容
            if (nodesInRedis != null){
                for (Object key : nodesInRedis.keySet()) {
                    //获取redis中新增或修改的节点信息
                    NodeBaseInfo newNode = (NodeBaseInfo) nodesInRedis.get(key);
//                    System.out.println("newNode："+newNode);
                    //如果newNode中的classId等于当前班级的nodeQueryInfo.getClassId()
                    if (newNode.getClassId().equals(nodeQueryInfo.getClassId())) {
                        //如果newNode中的stage等于当前阶段，则加入列表
                        if (newNode.getStage().equals(stage)){
                            nodeBaseInfos.add(new NodeBaseInfo(newNode.getNodeId(), newNode.getTitle(), newNode.getContent(), newNode.getClassId(),stage));
                        }
                    }
                }
            }
            for (int i=0; i < nodeBaseInfos.size(); i++){
                //读取deleteNode中的内容
                if (redisTemplate.hasKey("deleteNode")){
                    Map<Object,Object> deleteNodes = redisTemplate.opsForHash().entries("deleteNode");
                    if (deleteNodes != null){
                        for (Object key : deleteNodes.keySet()) {
                            NodeBaseInfo deleteNode = (NodeBaseInfo) deleteNodes.get(key);
                            //如果deleteNode中的classId等于当前班级的nodeQueryInfo.getClassId();
                            if (deleteNode.getClassId().equals(nodeQueryInfo.getClassId())) {
                                //如果deleteNode中的stage等于当前阶段，则从列表中删除和该节点id相同的节点
                                if (deleteNode.getStage().equals(stage) && nodeBaseInfos.get(i).getNodeId().equals(deleteNode.getNodeId())){
                                    nodeBaseInfos.remove(i);
                                }
                            }
                        }
                    }
                }
                //所有存入redis（nodeCache）
                redisTemplate.opsForHash().put("nodeCache", nodeBaseInfos.get(i).getNodeId(), nodeBaseInfos.get(i));
            }
            StageInfo stageInfo = new StageInfo(stage, nodeBaseInfos);
            stageInfos.add(stageInfo);

        }
        return stageInfos;
    }

    /**
     * 修改节点内容
     * @param node
     * @return
     */
    @Override
    //存redis
//    @CacheEvict( value = "nodeCache", key = "#node.nodeId")
    public boolean updateNodeInfo(Node node) {
        //存入redis
        NodeBaseInfo nodeBaseInfo = new NodeBaseInfo(node.getNodeId(), node.getTitle(), node.getContent(), node.getClassId(),node.getStage());
        redisTemplate.opsForHash().put("updateNode",node.getNodeId(),nodeBaseInfo);
        //同步修改nodeCache中该节点的值（只修改内容，还没考虑修改文件名的问题）
        redisTemplate.opsForHash().put("nodeCache",node.getNodeId(),nodeBaseInfo);

        if (node!=null){
            return true;
        }else {
            return false;
        }
    }
    /**
     * 修改node定时存入数据库
     */
    public void processUpdateNodesFromRedis() {
        System.out.println("修改node的定时任务");
        //读取redis中所有修改的节点信息
        Map<Object,Object> keyUpdateNode = redisTemplate.opsForHash().entries("updateNode");
        if (keyUpdateNode != null){
            //获取map集合（keyUpdateNode）中的所有keys
            Set<Object> keys = keyUpdateNode.keySet();
            for (Object key : keys) {
                //根据key获取map集合中的值
                NodeBaseInfo updateNode = (NodeBaseInfo) keyUpdateNode.get(key);
                //把新增的节点信息存入数据库中
                System.out.println("把redis中的修改节点存入数据库："+updateNode);
                Node node = new Node(updateNode.getNodeId(), updateNode.getTitle(), null, updateNode.getClassId(), updateNode.getContent(), updateNode.getStage(), null, null, null, null);
                nodeMapper.update(node);
            }
            //存入数据库中的所有节点信息，从redis中清除
            redisTemplate.delete("updateNode");
        }else {
            System.out.println("没有修改的节点");
        }
    }
    /**
     * 缓存已经找到的节点
     * @param nodeId
     * @return
     */
    @Override
//    @Cacheable(value = "nodeCache", key = "#nodeId")
    public Node getCurrentNode(String nodeId) {
        System.out.println("缓存已经找到的节点"+nodeId);
        //如果nodeCache不为空
        if (redisTemplate.hasKey("nodeCache")){
            //从nodeCache中获取节点信息
            NodeBaseInfo nodeCache = (NodeBaseInfo) redisTemplate.opsForHash().get("nodeCache", nodeId);
            System.out.println("选择的节点:"+nodeCache);
            Node node = new Node(nodeId,  nodeCache.getTitle(), null, nodeCache.getClassId(), nodeCache.getContent(), nodeCache.getStage(),null, null, null, null);
            return node;
        }else {
            Node node = nodeMapper.getNodeById(nodeId);
            return node;
        }


    }


        @Override
    public boolean delete(String nodeId,Integer stage, String classId) {
        //先存入redis中（deleteNode）
        System.out.println("删除节点："+nodeId);
        NodeBaseInfo deleteNode = new NodeBaseInfo(nodeId, null, null, classId, stage);
        redisTemplate.opsForHash().put("deleteNode",nodeId,deleteNode);
        //从nodeCache中删除该节点
        redisTemplate.opsForHash().delete("nodeCache",nodeId);
        return true;
    }

    @Override
    public Node getCurrentNodeByTitle(String title,String classId) {
        return nodeMapper.getNodeByTitle(title,classId);
    }

    /**
     * 删除node定时进入数据库
     */
    public void processDeleteNodesFromRedis() {
        System.out.println("删除node的定时任务");
        //读取redis中所有修改的节点信息
        Map<Object,Object> keyDeleteNode = redisTemplate.opsForHash().entries("deleteNode");
        if (keyDeleteNode != null){
            //获取map集合（keyUpdateNode）中的所有keys
            Set<Object> keys = keyDeleteNode.keySet();
            for (Object key : keys) {
                //根据key获取map集合中的值
                NodeBaseInfo deleteNode = (NodeBaseInfo) keyDeleteNode.get(key);
                //把新增的节点信息存入数据库中
                System.out.println("把redis中的删除节点进入数据库："+deleteNode);
//                Node node = new Node(deleteNode.getNodeId(), deleteNode.getTitle(), null, deleteNode.getClassId(), deleteNode.getContent(), deleteNode.getStage(), null, null, null, null);
                nodeMapper.delete(deleteNode.getNodeId());
            }
            //存入数据库中的所有节点信息，从redis中清除
            redisTemplate.delete("deleteNode");
        }else {
            System.out.println("没有删除的节点");
        }
    }
}
